package com.pactera.library.other;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import java.util.List;
import java.util.UUID;

/**
 * @author ypk
 * 创建日期：2021/9/10  14:29
 * 描述：
 */

public class BleManager11 {
    private static final String TAG = "BleManager";
    private static BleManager11 mBleManager;
    private static Context mContext;

    private BluetoothAdapter bluetoothAdapter;

    private Handler mh = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {

        }
    };


    public static synchronized BleManager11 getInstance(Context context) {
        if (mBleManager == null) {
            mBleManager = new BleManager11();
            mContext = context;
        }
        return mBleManager;
    }

    private BleManager11() {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    public BluetoothAdapter getBluetoothAdapter() {
        return bluetoothAdapter;
    }

    public void enableBLE() {
        //方法二：静默打开
        if (!bluetoothAdapter.isEnabled()) {
            //若没打开则打开蓝牙
            bluetoothAdapter.enable();
        }
    }

    public void startDiscoveryBLE() {
        if (bluetoothAdapter.isDiscovering()) { //如果当前在搜索，就先取消搜索
            bluetoothAdapter.cancelDiscovery();
        }
        bluetoothAdapter.startDiscovery();//开启搜索
    }

    public boolean connect(String address) {
        if (bluetoothAdapter.isDiscovering()) { //如果当前在搜索，就先取消搜索
            bluetoothAdapter.cancelDiscovery();
        }
        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
            Log.e(TAG, "the device address is invalid");
            return false;
        }

        final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.e(TAG, "no device");

            return false;
        }


        BluetoothGatt bluetoothGatt;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && device.getType() == BluetoothDevice.DEVICE_TYPE_DUAL) {
            bluetoothGatt = device.connectGatt(mContext, false, gattCallback, BluetoothDevice.TRANSPORT_LE);
        } else {
            bluetoothGatt = device.connectGatt(mContext, false, gattCallback);
        }
        if (bluetoothGatt != null) {
            // gattHashMap.put(address, bluetoothGatt);
            Log.d(TAG, "Trying to create a new connection.");
            return true;
        }
        return false;
    }

    private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        //当连接上设备或者失去连接时会回调该函数
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            BluetoothDevice device = gatt.getDevice();
            if (device == null) {
                return;
            }
            String address = device.getAddress();
            Log.i(TAG, "onConnectionStateChange----: address=" + address);
            //There is a problem here Every time a new object is generated that causes the same device to be disconnected and the connection produces two objects
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    Log.i(TAG, "onConnectionStateChange----: SUCCESS STATE_CONNECTED " + "status :" + status);
                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    Log.i(TAG, "onConnectionStateChange----: SUCCESS STATE_DISCONNECTED " + "status :" + status);
                }
            } else {
                //Occurrence 133 or 257 19 Equal value is not 0: Connection establishment failed due to protocol stack
                Log.e(TAG, "onConnectionStateChange----: " + "Connection status is abnormal:" + status);
            }

        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            if (gatt != null && gatt.getDevice() != null) {
                Log.d(TAG, "onMtuChanged mtu=" + mtu + ",status=" + status);

            }
        }

        //当设备是否找到服务时，会回调该函数
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            System.out.println(".onServicesDiscovered status=" + status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                initReadAndWriteCharacteristic(gatt.getServices());
            } else {
                Log.e(TAG, "onServicesDiscovered received: " + status);
            }
        }

        //当读取设备时会回调该函数
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (gatt == null || gatt.getDevice() == null) return;
            Log.d(TAG, "onCharacteristicRead:" + status);

        }

        // 写入操作的回调结果
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (gatt == null || gatt.getDevice() == null) return;
            Log.d(TAG, gatt.getDevice().getAddress() + "-----write success----- status: " + status);

        }

        /**
         * 当连接成功的时候会回调这个方法，这个方法可以处理发送密码或者数据分析
         * 当setnotify（true）被设置时，如果MCU（设备端）上的数据改变，则该方法被回调。
         * @param gatt 蓝牙gatt对象
         * @param characteristic 蓝牙通知特征对象
         */
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {

        }


        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            if (gatt == null || gatt.getDevice() == null) return;
            UUID uuid = descriptor.getCharacteristic().getUuid();
            Log.d(TAG, "write descriptor uuid:" + uuid);

        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(gatt, descriptor, status);
            if (gatt == null || gatt.getDevice() == null) return;
            UUID uuid = descriptor.getCharacteristic().getUuid();
            Log.d(TAG, "read descriptor uuid:" + uuid);

        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            Log.d(TAG, "read remoteRssi, rssi: " + rssi);
            if (gatt == null || gatt.getDevice() == null) return;

        }
    };

    BluetoothGattCharacteristic mReadCharacteristic;
    BluetoothGattCharacteristic mWriteCharacteristic;

    /**
     * 从发现的Service来找出读数据用的 BluetoothGattCharacteristic 和写数据用的 BluetoothGattCharacteristic。
     *
     * @param gattServices
     */
    public void initReadAndWriteCharacteristic(List<BluetoothGattService> gattServices) {
        if (gattServices == null) return;
        // 遍历所有的 GATT Services.
        for (BluetoothGattService gattService : gattServices) {
            String strUUID = gattService.getUuid().toString().trim();

            if (!strUUID.equalsIgnoreCase("这里是你期望的Service的uuid，由你司智能外色的驱动工程师决定"))
                continue;
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
            // 遍历当前Service中所有的Characteristics.
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                if (gattCharacteristic.getUuid().toString().trim().equalsIgnoreCase("这里是你期望的写数据的uuid，由你司驱动工程师决定")) {
                    mWriteCharacteristic = gattCharacteristic;
                } else if (gattCharacteristic.getUuid().toString().trim().equalsIgnoreCase("这里是你期望的读数据的uuid，由你司驱动工程师决定")) {
                    mReadCharacteristic = gattCharacteristic;
                }
            }
        }
    }

 /*

 private boolean mScanning;

    public boolean isScanning() {
        return mScanning;
    }
 public void scanLeDevice(final boolean enable, BluetoothAdapter.LeScanCallback callback) {
         if (!bluetoothAdapter.isEnabled()) {
             bluetoothAdapter.enable();
             return;
         }
         if (enable) {
             // Stops scanning after a pre-defined scan period.
             new Handler().postDelayed(new Runnable() {
                 @Override
                 public void run() {
                     mScanning = false;
                     bluetoothAdapter.stopLeScan(callback);
                 }
             }, 10 * 1000);

             mScanning = true;

             bluetoothAdapter.startLeScan(callback);
         } else {
             mScanning = false;
             bluetoothAdapter.stopLeScan(callback);
         }
     }*/
   /* public void scanLeDevice(final boolean enable, ScanCallback callback) {
        if (!bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.enable();
            return;
        }
        BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    bluetoothLeScanner.stopScan(callback);
                }
            }, 10 * 1000);
            mScanning = true;
            bluetoothLeScanner.startScan(callback);
        } else {
            mScanning = false;
            bluetoothLeScanner.stopScan(callback);
        }
    }*/
}
